-
Notifications
You must be signed in to change notification settings - Fork 186
Readme #462
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Readme #462
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR significantly enhances the Kotlin MCP SDK documentation by expanding the README with comprehensive usage examples, adding detailed module documentation, and integrating the Knit tool for validating code snippets. The update transforms minimal documentation into a complete developer guide with quickstart examples, core concepts, and feature demonstrations.
- Expanded README from basic overview to comprehensive guide with installation instructions, quickstart examples, and detailed feature documentation
- Added extensive module documentation (Module.md) for core, client, and server packages with code examples
- Integrated Knit build tool for automated code snippet validation
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| settings.gradle.kts | Added :docs module to the build |
| gradle/libs.versions.toml | Added knit plugin version 0.5.0 and fixed junit formatting |
| docs/build.gradle.kts | Created build configuration for docs module with knit plugin setup |
| docs/.gitignore | Added gitignore to exclude knit-generated sources |
| knit.properties | Created knit configuration for code snippet extraction |
| README.md | Completely rewrote with table of contents, comprehensive examples, core concepts, transports, and API documentation |
| kotlin-sdk-core/Module.md | Expanded from minimal overview to detailed module documentation with usage examples |
| kotlin-sdk-client/Module.md | Expanded with comprehensive client setup examples and feature descriptions |
| kotlin-sdk-server/Module.md | Expanded with server setup examples, feature registration details, and lifecycle information |
| docs/moduledoc.md | Streamlined and updated module overview with clearer structure and updated code examples |
| .github/workflows/build.yml | Added knit validation step to the CI build workflow |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| <!--- KNIT example-server-util-pagination-01.kt --> | ||
|
|
||
| Include `nextCursor` only when more items remain an absent cursor ends pagination. |
Copilot
AI
Dec 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a missing punctuation mark between "remain" and "an". The sentence should either use a period, semicolon, or conjunction. Consider: "Include nextCursor only when more items remain. An absent cursor ends pagination." or "Include nextCursor only when more items remain; an absent cursor ends pagination."
| Include `nextCursor` only when more items remain an absent cursor ends pagination. | |
| Include `nextCursor` only when more items remain. An absent cursor ends pagination. |
kpavlov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @devcrocod
I’ve noticed that Knit isn’t being applied to MD files, even though it’s been added. Let’s consider enabling it in the next PRs.
Also, would it be a good idea to move the examples from _Module.md_s to the main README.md? That way, it’ll be easier for people and AI agents to find them. What do you think?
| A minimal client: | ||
| Minimal WebSocket client: | ||
|
|
||
| ```kotlin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's enable knit for this example
| // Build and return a CallToolResult from request.arguments | ||
| // (see CallToolResult and related types in kotlin-sdk-core) | ||
| /* ... */ | ||
| fun Application.module() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's enable knit for this example
|
|
||
| ### Minimal STDIO client | ||
|
|
||
| ```kotlin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's add knit for the example too
|
|
||
| ### Minimal STDIO server | ||
|
|
||
| ```kotlin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's add knit
|
|
||
| ### Hosting with Ktor (SSE) | ||
|
|
||
| ```kotlin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kint
In this PR, I added knit only for the Readme.md file for now. I haven’t set it up for the module.md files yet. We can add that later. For now, I only updated those files because they were outdated
For now, I prefer not to do this |
|
I don't agree, that Readme would get too crowded. It’s pretty standard these days to have a one-page manual, and that’s what I’m getting at. You could use the Detailstag in HTML to hide the examples, which would make it look nicer for people, but still give AI/crawlers all the info they need. |
4f9927c to
da90e1b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 13 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
kotlin-sdk-core/Module.md
Outdated
| @@ -1,5 +1,47 @@ | |||
| # Module kotlin-sdk-core | |||
| # kotlin-sdk-core | |||
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Module.md files are included into Dokka via buildSrc/src/main/kotlin/mcp.dokka.gradle.kts:10 (includes.from("Module.md")). Dokka’s module documentation format expects the header to start with # Module <module-name>; changing this to # kotlin-sdk-core may prevent the content from being recognized as module docs. Consider restoring the # Module kotlin-sdk-core heading.
| # kotlin-sdk-core | |
| # Module kotlin-sdk-core |
| 1. Declare client capabilities with `ClientOptions` (e.g., tools, prompts, resources, logging, roots, sampling, | ||
| elicitation). |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ClientCapabilities in this repo only models client-advertised capabilities (sampling, roots, elicitation, experimental). Mentioning tools/prompts/resources/logging here is misleading because those are server capabilities, and it suggests configuration options that don’t exist on ClientCapabilities. Update the wording to reflect the actual fields.
| clientOptions = ClientOptions( | ||
| capabilities = ClientCapabilities( | ||
| tools = ClientCapabilities.Tools(), | ||
| resources = ClientCapabilities.Resources(subscribe = true), | ||
| ) | ||
| ), |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example won’t compile: ClientCapabilities has no Tools/Resources nested types nor tools/resources properties (see kotlin-sdk-core/src/commonMain/.../capabilities.kt). Use ClientOptions() (default) or set only supported fields like roots/sampling/elicitation.
| clientOptions = ClientOptions( | |
| capabilities = ClientCapabilities( | |
| tools = ClientCapabilities.Tools(), | |
| resources = ClientCapabilities.Resources(subscribe = true), | |
| ) | |
| ), | |
| clientOptions = ClientOptions(), |
| - **SSE** (streaming GET + POST back-channel): create `SSEClientTransport(baseUrl, httpClient)`; sessions are keyed by | ||
| `sessionId` managed by the SDK. | ||
| - **WebSocket**: use `WebSocketClientTransport(url, httpClient)` to get bidirectional messaging in one connection. | ||
| - **Streamable HTTP**: `StreamableHttpClientTransport` enables MCP over streaming HTTP where WebSockets are unavailable. |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The transport constructor examples here don’t match the actual APIs:
SSEClientTransportis a typealias deprecated withDeprecationLevel.ERRORin favor ofSseClientTransport.SseClientTransport/WebSocketClientTransportconstructors take(httpClient, url)(or preferHttpClient.mcpSseTransport(...)/HttpClient.mcpWebSocketTransport(...)).
Update these backticked call patterns so they’re copy/paste correct.
| val server = Server( | ||
| serverInfo = Implementation(name = "demo-server", version = "1.0.0"), | ||
| options = ServerOptions( | ||
| capabilities = ServerCapabilities( | ||
| tools = ServerCapabilities.Tools(listChanged = true) | ||
| ) | ||
| ) | ||
| ) { | ||
| addTool( | ||
| name = "hello", | ||
| description = "Greets the caller by name" | ||
| ) { request -> | ||
| val name = request.params.arguments["name"]?.jsonPrimitive?.content ?: "there" | ||
| CallToolResult( | ||
| content = listOf(TextContent("Hello, $name!")), | ||
| isError = false, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| val transport = StdioServerTransport(System.`in`.source(), System.out.sink()) | ||
| server.createSession(transport) |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This snippet uses APIs that don’t exist / won’t compile as written:
System.in.source()/System.out.sink()should beasSource()/asSink()(kotlinx-io).Server.createSession(...)issuspend, so calling it at top-level (outside asuspend fun main/runBlocking) isn’t valid Kotlin.
Consider updating the example to asuspend fun main(orrunBlocking) and use the correct stdio adapters.
| val server = Server( | |
| serverInfo = Implementation(name = "demo-server", version = "1.0.0"), | |
| options = ServerOptions( | |
| capabilities = ServerCapabilities( | |
| tools = ServerCapabilities.Tools(listChanged = true) | |
| ) | |
| ) | |
| ) { | |
| addTool( | |
| name = "hello", | |
| description = "Greets the caller by name" | |
| ) { request -> | |
| val name = request.params.arguments["name"]?.jsonPrimitive?.content ?: "there" | |
| CallToolResult( | |
| content = listOf(TextContent("Hello, $name!")), | |
| isError = false, | |
| ) | |
| } | |
| } | |
| val transport = StdioServerTransport(System.`in`.source(), System.out.sink()) | |
| server.createSession(transport) | |
| import kotlinx.io.asSink | |
| import kotlinx.io.asSource | |
| suspend fun main() { | |
| val server = Server( | |
| serverInfo = Implementation(name = "demo-server", version = "1.0.0"), | |
| options = ServerOptions( | |
| capabilities = ServerCapabilities( | |
| tools = ServerCapabilities.Tools(listChanged = true) | |
| ) | |
| ) | |
| ) { | |
| addTool( | |
| name = "hello", | |
| description = "Greets the caller by name" | |
| ) { request -> | |
| val name = request.params.arguments["name"]?.jsonPrimitive?.content ?: "there" | |
| CallToolResult( | |
| content = listOf(TextContent("Hello, $name!")), | |
| isError = false, | |
| ) | |
| } | |
| } | |
| val transport = StdioServerTransport(System.`in`.asSource(), System.out.asSink()) | |
| server.createSession(transport) | |
| } |
kotlin-sdk-client/Module.md
Outdated
| @@ -1,10 +1,74 @@ | |||
| # Module kotlin-sdk-client | |||
| # kotlin-sdk-client | |||
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Module.md files are included into Dokka via buildSrc/src/main/kotlin/mcp.dokka.gradle.kts:10 (includes.from("Module.md")). Dokka’s module documentation format expects the header to start with # Module <module-name>; changing this to # kotlin-sdk-client may prevent the content from being recognized as module docs. Consider restoring the # Module kotlin-sdk-client heading.
| # kotlin-sdk-client | |
| # Module kotlin-sdk-client |
| resources = ClientCapabilities.Resources(subscribe = true), | ||
| ) | ||
| ), | ||
| transport = StdioClientTransport(System.`in`.source(), System.out.sink()) |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
System.in.source() / System.out.sink() aren’t APIs provided by this codebase’s stdio transports (they use kotlinx.io.asSource()/asSink() + buffered()). As written, the snippet won’t compile for readers. Update the example to use the kotlinx.io adapters consistent with the SDK’s own docs/tests.
kotlin-sdk-server/Module.md
Outdated
| @@ -1,14 +1,122 @@ | |||
| # Module kotlin-sdk-server | |||
| # kotlin-sdk-server | |||
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Module.md files are included into Dokka via buildSrc/src/main/kotlin/mcp.dokka.gradle.kts:10 (includes.from("Module.md")). Dokka’s module documentation format expects the header to start with # Module <module-name>; changing this to # kotlin-sdk-server may prevent the content from being recognized as module docs. Consider restoring the # Module kotlin-sdk-server heading.
| # kotlin-sdk-server | |
| # Module kotlin-sdk-server |
| name = "hello", | ||
| description = "Greets the caller by name" | ||
| ) { request -> | ||
| val name = request.params.arguments["name"]?.jsonPrimitive?.content ?: "there" |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CallToolRequestParams.arguments is nullable (JsonObject?). Indexing directly (request.params.arguments["name"]) won’t compile. Use request.arguments?.get("name") (or request.params.arguments?.get("name")) before accessing jsonPrimitive.
| val name = request.params.arguments["name"]?.jsonPrimitive?.content ?: "there" | |
| val name = request.params.arguments?.get("name")?.jsonPrimitive?.content ?: "there" |
| val client = mcpClient( | ||
| clientInfo = Implementation("sample-client", "1.0.0"), | ||
| clientOptions = ClientOptions(ClientCapabilities(tools = ClientCapabilities.Tools())), | ||
| transport = WebSocketClientTransport("ws://localhost:8080/mcp") |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This WebSocket client example won’t compile:
ClientCapabilitieshas notools/Tools(client capabilities aresampling/roots/elicitation/experimental).WebSocketClientTransportrequires anHttpClientargument (or useHttpClient.mcpWebSocketTransport(url)), not just a URL string.
Update the snippet to match the actual constructors/types.
| val client = mcpClient( | |
| clientInfo = Implementation("sample-client", "1.0.0"), | |
| clientOptions = ClientOptions(ClientCapabilities(tools = ClientCapabilities.Tools())), | |
| transport = WebSocketClientTransport("ws://localhost:8080/mcp") | |
| val httpClient = HttpClient() | |
| val client = mcpClient( | |
| clientInfo = Implementation("sample-client", "1.0.0"), | |
| clientOptions = ClientOptions(ClientCapabilities()), | |
| transport = WebSocketClientTransport(httpClient, "ws://localhost:8080/mcp"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
#162
Motivation and Context
How Has This Been Tested?
knit
Breaking Changes
None
Types of changes
Checklist